package com.hhh.Service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hhh.Dto.DishDto;
import com.hhh.ExceptionHandle.DishException;
import com.hhh.Mapper.DishMapper;
import com.hhh.Pojo.Category;
import com.hhh.Pojo.Dish;
import com.hhh.Pojo.DishFlavor;
import com.hhh.Service.CategoryService;
import com.hhh.Service.DishFlavorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.zip.DataFormatException;

@Service
@Slf4j
public class DishService implements com.hhh.Service.DishService {
    @Autowired
    DishMapper dishMapper;

    @Autowired
    DishFlavorService dishFlavorService;

    @Autowired
    CategoryService categoryService;

    //    查询菜品
//    因为前端页面要展示的是分类的名字，
//    所以要用DishDto类返回
    @Override
    @Transactional
    public IPage<DishDto> SelectAll(long page, long pageSize, String name) {
        IPage<Dish> iPage = new Page<>(page, pageSize);
        QueryWrapper<Dish> wrapper = new QueryWrapper<>();
        if (name != null) {
            wrapper.eq("name", name);
        }

//        把disharr的属性copy到dishDtoIPage，除了records
        IPage<Dish> disharr = dishMapper.selectPage(iPage, wrapper);
        IPage<DishDto> dishDtoIPage = new Page<>();
        BeanUtils.copyProperties(disharr, dishDtoIPage, "records");

//        转化Records里面的对象类型
        List<DishDto> dishDtoarr = disharr.getRecords().stream().map(new Function<Dish, DishDto>() {
            @Override
            public DishDto apply(Dish dish) {
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(dish, dishDto);
                Category category = categoryService.SelectById(dish.getCategoryId());
                dishDto.setCategoryName(category.getName());
                return dishDto;
            }
        }).toList();

        return dishDtoIPage.setRecords(dishDtoarr);
    }

    //    根据id查询菜品
    @Override
    @Transactional
    public DishDto SelectById(long id) {
        Dish dish = dishMapper.selectById(id);

        DishDto dishDto = new DishDto();

//        把dish的属性赋给dishDto
//        可以用BeanUtils.copyProperties 更简单
        dishDto.setId(dish.getId());
        dishDto.setName(dish.getName());
        dishDto.setCategoryId(dish.getCategoryId());
        dishDto.setPrice(dish.getPrice());
        dishDto.setCode(dish.getCode());
        dishDto.setImage(dish.getImage());
        dishDto.setDescription(dish.getDescription());
        dishDto.setStatus(dish.getStatus());
        dishDto.setSort(dish.getSort());

        List<DishFlavor> dishFlavorarr = dishFlavorService.SelectByDishID(id);
        dishDto.setFlavors(dishFlavorarr);
        return dishDto;
    }

    //    根据CategoryId查询数据条数
    @Override
    public long SelectCount(long CategoryId) {
        QueryWrapper<Dish> wrapper = new QueryWrapper<>();
        wrapper.eq("category_id", CategoryId);
        return dishMapper.selectCount(wrapper);
    }

    //    添加菜品
    @Override
    @Transactional
    public Integer Insert(DishDto dishDto) {
        Integer num1 = dishMapper.insert(dishDto);
        List<DishFlavor> dishFlavorList = dishDto.getFlavors();
        int num = 0;
        Integer len = dishDto.getFlavors().size();
        while (num < len && (dishDto.getFlavors().get(num)) != null) {
            dishFlavorList.get(num).setDishId(dishDto.getId());
            num++;
        }
        Integer num2 = dishFlavorService.Insert(dishFlavorList);
        return num1 == 1 && num2 == 1 ? 1 : 0;
    }

    //    修改菜品
    @Override
    @Transactional
    public Integer Upate(DishDto dishDto) {
        QueryWrapper<Dish> wrapper = new QueryWrapper<>();
        wrapper.eq("id", dishDto.getId());
        log.info("修改菜品");
//        修改菜品
        Integer num1 = dishMapper.update(dishDto, wrapper);
//        修改菜品口味
//        全部删除重新添加
        Integer deletenum = dishFlavorService.DeleteByDishId(dishDto.getId());
        List<DishFlavor> dishFlavorList = dishDto.getFlavors();
        for (DishFlavor dishFlavor : dishFlavorList)
            dishFlavor.setDishId(dishDto.getId());
        Integer num2 = dishFlavorService.Insert(dishFlavorList);
        if (num1 == 1 && num2 != null & deletenum != null)
            return 1;
        else
            return 0;
    }

    //    根据分类id查询菜品
//    之所以传DsihDto
//    是因为前端在展示菜品的时候需要加载菜品口味
    @Override
    @Transactional
    public List<DishDto> SelectByCategoryId(long CategoryId) {
        List<DishDto> dishDtoList = new ArrayList<>();

        QueryWrapper<Dish> wrapper = new QueryWrapper<>();
        wrapper.eq("category_id", CategoryId);
        List<Dish> dishList = dishMapper.selectList(wrapper);
        for (Dish dish : dishList) {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            dishDtoList.add(dishDto);
        }

        for (DishDto tempdishDto : dishDtoList) {
            tempdishDto.setFlavors(dishFlavorService.SelectByDishID(tempdishDto.getId()));
        }
        return dishDtoList;
    }

    //    更改dish的status
    @Override
    public Integer Updatestatus(Integer status, List<Long> ids) {
        int num = 0;
        for (long id : ids) {
            Dish dish = new Dish();
            dish.setId(id);
            dish.setStatus(status);
            num += dishMapper.updateById(dish);
        }
        return num;
    }

    //    删除菜品
    @Override
    @Transactional
    public Integer Delete(List<Long> ids) {
        int num = 0;
        for (long id : ids) {
            Dish dish = dishMapper.selectById(id);
            if (dish.getStatus() != 0)
                throw new DishException("菜品未停售，无法删除");
            num += dishMapper.deleteById(id);
            dishFlavorService.DeleteByDishId(id);
        }
        return num;
    }
}
